﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Xml;

using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.packager.standardPackageActions;
using umbraco.interfaces;

namespace CreativeMinds.Umbraco.Installation.PackageActions {

	/// <summary>
	/// The package action will execute the queries found in the action xml.
	/// Example xml can be found in the resource files
	/// </summary>
	public class ExecuteSQL : PackageAction, IPackageAction {

		/// <summary>
		/// The alias of the package. This alias must be unique and is use to identify the package action to use.
		/// </summary>
		/// <returns>The alias of the package</returns>
		public override string Alias() {
			return "ExecuteSQL";
		}

		/// <summary>
		/// Install method for the package.
		/// </summary>
		/// <param name="packageName">Name of the package to be installed.</param>
		/// <param name="xmlData">The node for the package from the actions xml.</param>
		/// <returns>True if the installation succeeded</returns>
		protected override bool Install(string packageName, XmlNode xmlData) {
			if (xmlData.Attributes.GetNamedItem("installsql") != null) {
				XmlDocument sqlData = new XmlDocument();
				sqlData.Load(HttpContext.Current.Server.MapPath(xmlData.Attributes.GetNamedItem("installsql").Value));
				return HandleQueries(sqlData.SelectNodes("Data/Install/Query"));
			}
			else {
				return HandleQueries(xmlData.SelectNodes("Install/Query"));
			}
		}

		/// <summary>
		/// Method that takes the given xml nodes and gets the sql executed.
		/// </summary>
		/// <param name="queries">A list of xml nodes with sql queries.</param>
		/// <returns>True if the execution succeeded</returns>
		private bool HandleQueries(XmlNodeList queries) {
			try {
				List<SQLPackage> packages = new List<SQLPackage>();
				foreach (XmlNode query in queries) {
					// Create a sql package from the text content of the current node!
					packages.Add(new SQLPackage(query));
				}

				// Create a database helper and execute the packages!
				new DatabaseHelper(WebConfig.Instance.ConnectString, packages).Execute();
			}
			catch (Exception ex) {
				// An error occured, let's bail out without saving any changes!
				Log.Add(LogTypes.Error, -1, String.Format("{1}{0}{2}{0}{3}", Environment.NewLine, ex.TargetSite, ex.Message, ex.StackTrace));
				return false;
			}
			return true;
		}

		/// <summary>
		/// Uninstall method for the package.
		/// </summary>
		/// <param name="packageName">Name of the package to be uninstalled.</param>
		/// <param name="xmlData">The node for the package from the actions xml.</param>
		/// <returns>True if the uninstallation succeeded</returns>
		protected override bool Uninstall(string packageName, XmlNode xmlData) {
			if (xmlData.Attributes.GetNamedItem("uninstallsql") != null) {
				XmlDocument sqlData = new XmlDocument();
				sqlData.Load(HttpContext.Current.Server.MapPath(xmlData.Attributes.GetNamedItem("uninstallsql").Value));
				return HandleQueries(sqlData.SelectNodes("Data/Uninstall/Query"));
			}
			else {
				return HandleQueries(xmlData.SelectNodes("Uninstall/Query"));
			}
		}

		/// <summary>
		/// Returns a sample xml node, in this case including the sql for creating a table.
		/// </summary>
		/// <returns>A xml node containing an example of the required data for this package</returns>
		public override XmlNode SampleXml() {
			return helper.parseStringToXmlNode(String.Format(Resource1.ExecuteSql, this.Alias()));
		}
	}
}